<?php
// ----------------------------------------------------------------------
// pn-commerce Shopping Cart Solution for PostNuke
// http://pncommerce.de
// http://www.sourceforge.net/projects/pn-commerce/
//
// It is based on PostKart 0.701QA from
//          Destin LeBlanc [ postkart@zenflesh.com ]
// ----------------------------------------------------------------------
// Source file:  $Source: /cvsroot/pn-commerce/pn-commerce/pnpmcreditapi.php,v $
//
// Last changes from:  $Author: jimhadfield $
//
// Revision:           $Revision: 1.37 $
//
// Date of revision    $Date: 2005/08/20 10:41:03 $
//  
// ----------------------------------------------------------------------
// LICENSE
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License (GPL)
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// To read the license please visit http://www.gnu.org/copyleft/gpl.html
// ----------------------------------------------------------------------

require_once("modules/pncommerce/common.php");

/**
 * load the config array and return it
 * no arguments needed
 */
function pncommerce_pmcreditapi_getConfig ($args)
{
    $data=pnModGetVar ('pncommerce', 'pmcreditData');
    if(isset($data)) {
        return unserialize($data);
    }
    return false;
}

/**
 * save the config array
 * @param $args array of config values
 */
function pncommerce_pmcreditapi_setConfig ($args)
{
    pnModSetVar ('pncommerce', 'pmcreditData',serialize($args));
}



/**
 * This function is used during the checkout process
 * it's called after the checkout where the user agrees to
 * buy the items, so you can do the rest here to finish the
 * payment process if possible. otherwise just redirect to the next step
 * called processshippingfinal
 * don't forget to bypass all important informations 
 * like ON,KID,maxStep
 * it's important when the user jumps back to earlier steps
 *
 * @param $args['KID'] string CustomerID
 * @param $args['ON']  string order number
 */
function pncommerce_pmcreditapi_processpayment ($args)
{ 
    pnRedirect( pnModURL( 'pncommerce', 'user', 'processshippingfinal' ) );
    return true;
}

/**
 * This function is used during the checkout process
 * you can let the user provide special information
 * you need for further processing
 * when you don't need any info just redirect the user to
 * getshippingmethod in the pnuser.php
 * don't forget to bypass all important informations 
 * like BPM,BSM,KID,maxStep
 * it's important when the user jumps back to earlier steps
 * @param $args['user'] array with user data
 */
function pncommerce_pmcreditapi_getdata ($args)
{
    extract ($args);
    
    if (!pnModAPILoad( 'pncommerce', 'user')) {
        return showerrorpage("unable to load pnuserapi", __FILE__, __LINE__);
    }

    $decryptedCCNum= decrypt($user['PayMethodData']['CCNum']);
    $config = pncommerce_pmcreditapi_getConfig();

    $card[1]['num'] = 1;
    $card[2]['num'] = 2;
    $card[3]['num'] = 3;
    $card[1]['name'] = _PNC_CARD1;
    $card[2]['name'] = _PNC_CARD2;
    $card[3]['name'] = _PNC_CARD3;
    $card[1]['active'] = $config['card1'];
    $card[2]['active'] = $config['card2'];
    $card[3]['active'] = $config['card3'];
    $card[1]['checked'] = "";
    $card[2]['checked'] = "";
    $card[3]['checked'] = "";
    // step 1: see if the users last used card is still active and mark this for now
    if( ( $config['card1'] == 'on' ) && ( $user['PayMethodData']['CCType'] == 1) ) {
        $card[1]['checked'] = "checked";
    } elseif( ( $config['card2'] == 'on' ) && ( $user['PayMethodData']['CCType'] == 2) ) {
        $card[2]['checked'] = "checked";
    } elseif( ( $config['card2'] == 'on' ) && ( $user['PayMethodData']['CCType'] == 3) ) {
        $card[3]['checked'] = "checked";
    } else {
        // step 2: users last used card is invalid or he did not use a card yet
        // we will activate the first of the three cards we find as active (there is at
        // least one, the configuration takes care of this)
        if( $config['card1'] == 'on' ) {
            $card[1]['checked'] = "checked";
        } elseif( $config['card2'] == 'on' ) {
            $card[2]['checked'] = "checked";
        } elseif( $config['card3'] == 'on' ) {
            $card[3]['checked'] = "checked";
        }
    }

    $smarty =& new pnRender('pncommerce');
    $smarty->caching = false;
    $smarty->assign( 'decryptedCCNum', $decryptedCCNum );
    $smarty->assign( 'cards', $card );
    $smarty->assign( 'user', unserialize( pnSessionGetVar( 'PNCUserData' ) ) );
    return $smarty->fetch( 'pncommerce_pmcredit_getdata.html' );
}

/**
 * This function is used during the checkout process
 * you can save the provide information here
 * getshippingmethod in the pnuser.php
 * don't forget to bypass all important informations 
 * like BPM,BSM,KID,maxStep
 * it's important when the user jumps back to earlier steps
 * 
 * It's important to redirect to getshippingmethod if everything was ok here
 *
 * @param $args['KID'] string CustomerID
 * @param $args['BPM'] string selected Paymethod
 * @param $args['BSM'] string selected Shippingmethod
 * @param $args['maxStep'] int highest Step the user reached in this checkout process
 */
function pncommerce_pmcreditapi_getdataresponse($args)
{
    if (!pnModAPILoad( 'pncommerce', 'user')) {
        return showerrorpage("unable to load pnuserapi", __FILE__, __LINE__);
    }
    
    $config = pncommerce_pmcreditapi_getConfig();
    $user = unserialize( pnSessionGetVar( 'PNCUserData' ) );
    list($user['PayMethodData']['CCType'],
         $CCNum,
         $user['PayMethodData']['CCExpire'],
         $user['PayMethodData']['CCVerifyCode']) = pnVarCleanFromInput( 'CCType', 'CCNum', 'CCExpire', 'CCVerifyCode');

    // check if CCNum starts with 'XXXX XXXX XXXX', in this case we received a disguised card
    // number and must see if we already have a valid number in the users array
    if(strpos($CCNum, 'XXXX XXXX XXXX')===false) {
        $user['PayMethodData']['CCNum'] = encrypt($CCNum);
        // encrypt the ccnumber if wanted
    }

    pnSessionSetVar( 'PNCUserData', serialize( $user ) );

    if($user['PayMethodData']['CCType'] == "0") {
        $errormsg[] = ""._PNC_YOUFORGOT." "._PNC_CCTYPECAPS.". "._PNC_PLEASEGOBACK;
    }
    if(empty($user['PayMethodData']['CCNum'])) {
        $errormsg[] = ""._PNC_YOUFORGOT." "._PNC_CCNUMBERCAPS.". "._PNC_PLEASEGOBACK;
    }
    if(empty($user['PayMethodData']['CCExpire'])) {
        $errormsg[] = ""._PNC_YOUFORGOT." "._PNC_CCEXPIRECAPS.". "._PNC_PLEASEGOBACK;
    }
    if(empty($user['PayMethodData']['CCVerifyCode'])) {
        $errormsg[] = ""._PNC_YOUFORGOT." "._PNC_CCVERIFYCODECAPS.". "._PNC_PLEASEGOBACK;
    }
    if ( count( $errormsg ) > 0 ) {
        $smarty = new pnRender();
        $smarty->caching = false;
        $smarty->assign( 'errormsg', $errormsg );
        $smarty->assign( 'user', $user );
        return $smarty->fetch( 'pncommerce_pmcredit_getdataresponse.html' );
    } else {
        // save the data to the db table users
        pncommerce_pmcreditapi_userinsert (array('user' => $user));
    }
    pnRedirect( pnModURL ( 'pncommerce', 'user', 'getshippingmethod' ) );
    return true;
}

function pncommerce_pmcreditapi_userinsert($args)
{
    extract ($args);
    
    $user['PayMethodData']['CCNum'] = str_replace(" ", "", $user['PayMethodData']['CCNum'] );
    if (!pnModAPILoad('pncommerce', 'user')) {
        return showerrorpage("unable to load pnuserapi", __FILE__, __LINE__);
    }

    list($dbconn, $pntables) = pncOpenDB();
    $tablename = $pntables['pncommerce_users'];
    $column = $pntables['pncommerce_users_column'];
    $sql = "UPDATE $tablename 
            SET $column[PayMethod]='pmcredit',
                $column[PayMethodData]='".pnVarPrepForStore(serialize($user['PayMethodData']))."' 
            WHERE UserName='".pnVarPrepForStore($user['KID'])."'";
    $result = pncExecuteSQL($dbconn, $sql, __FILE__, __LINE__);
    pncCloseDB($result);
//    pnModAPIFunc ('pncommerce', 'user', 'executesqlDB', 
//                   array ('sql' => $sql));
    return;
}

function pncommerce_pmcreditapi_order($args)
{
    extract ($args);
    if (!pnModAPILoad('pncommerce', 'user')) {
        return showerrorpage("unable to load pnuserapi", __FILE__, __LINE__);
    }

    $data = pnModAPIFunc ('pncommerce', 'user', 'readfromDB',
                                    array('table' => 'users',
                                        'fields' => array ('payMethodData'),
                                        'required' => array ('UserName', $KID)));
    if($data!=false) {
        $data=$data[0];
    } else {
        pnSessionSetVar('errormsg', _PNC_NODATA);
        return false;
    }
    pnModAPIFunc ('pncommerce', 'user', 'executesqlDB', array ('sql' => "UPDATE ".pnConfigGetVar('prefix')."_pncommerce_orders SET PayMethodData='".pnVarPrepForStore($data)."' WHERE OrderNumber='".(int)$ON."'"));
}

function pncommerce_pmcreditapi_configintro ($args)
{
    $Mode = pnVarCleanFromInput ('Mode');
    if (!pnModAPILoad('pncommerce', 'user')) {
        return showerrorpage("unable to load pnuserapi", __FILE__, __LINE__);
    }
    if (pnSecAuthAction(0, '::', '::', ACCESS_ADMIN)) {
        switch ($Mode) {
        case 'install':
            $default=array('PMCalcFunc'=>'PMCFlat',
                            'PMCFlatPrice' => '0',
                            'card1' => 'on',
                            'card2' => 'on',
                            'card3' => 'on',
                            'usemcrypt' => 'on',
                            'mcryptkey' => 'pleasechangethesecretkey' );
            pncommerce_pmcreditapi_setConfig($default);
            pnModSetVar ('pncommerce', 'pmcredit', 'on');
            break;
        case 'remove':
            pncommerce_pmcreditapi_quietremove();
            break;
        case 'activate':
            pnModSetVar ('pncommerce', 'pmcredit', 'on');
            break;
        case 'deactivate':
            pnModSetVar ('pncommerce', 'pmcredit', 'off');
            break;
        default:
            break;
        }
        pnRedirect( pnModAPIFunc('pncommerce','user','pncModURL',
                                array('Module'=>'pncommerce', 'Section'=> 'admin', 'Function'=>'paymethodconfig')));
        return true;
    } else {
        return showerrorpage( _PNC_NOAUTH, __FILE__, __LINE__ );
    }

}

function pncommerce_pmcreditapi_showoption($args)
{
    extract ($args);
    $temp ="<input type='radio' name='PayMethod' value='pmcredit'";
    if ( $BPM == 'pmcredit' )
    {
        $temp .= " checked ";
    }
    $temp .= ">"._PNC_CCORDER."<br>";
    return $temp;
}

function pncommerce_pmcreditapi_info ()
{
    return (_PNC_CCORDER);
}

function pncommerce_pmcreditapi_footermsg ($args)
// $ON or $KID, but never both at the same time !!!
// only $ON  : we already have an order and read the fields from there
// only $KID : we don't have an order yet and read from the users table
{
    extract ($args);
    $config = pncommerce_pmcreditapi_getConfig();

    $cr = "<br>";
    if (!pnModAPILoad('pncommerce', 'user')) {
        return showerrorpage("unable to load pnuserapi", __FILE__, __LINE__);
    }
    if(isset($KID)) {
        $data = pnModAPIFunc ('pncommerce', 'user', 'readfromDB',
                                        array('table' => 'users',
                                            'fields' => array ('PayMethodData'),
                                            'required' => array ('UserName', $KID)));
    } else if (isset($ON)) {
        $data = pnModAPIFunc ('pncommerce', 'user', 'readfromDB',
                                        array('table' => 'orders',
                                            'fields' => array ('PayMethodData'),
                                            'required' => array ('OrderNumber', $ON)));
    } else {
        // internal error
        return ("Internal error when creating footermsg in creditapi<br>");
    }
    $ccdata = unserialize($data[0]);

    $decryptedCCNum = decrypt($ccdata['CCNum']);
    // "<font class=\"pn-normal\">
    $cardname = array ('American Express', 'Euro/MasterCard', 'VisaCard');
    $temp = "".$cardname[(int)$ccdata['CCType']-1].$cr;
    $temp = $temp._PNC_CCNUMBER.": " . $decryptedCCNum . " " . $cr;
    $temp = $temp._PNC_CCEXPIRE.": " . $ccdata['CCExpire'] . " " . $cr;
    $temp = $temp._PNC_WEWILLSHIPUPONAPPROVAL.$cr;
    return $temp;
}

function pncommerce_pmcreditapi_quietremove ()
{
    pnModDelVar ('pncommerce', 'pmcredit');
    pnModDelVar ('pncommerce', 'pmcreditData');
}

/**
 * This function is used during the checkout process
 * You can calculate a fee for the selected paymethod here
 *
 * @param $args['SubTotal'] Double the total costs with shipping included
 * @return double 
 * @returns the fee for this paymethod
 */
function pncommerce_pmcreditapi_getPaymethodTotal($args)
{
//Return 0 = this Paymethod is for free
    if (!pnModAPILoad('pncommerce', 'user')) {
        return showerrorpage("unable to load pnuserapi", __FILE__, __LINE__);
    }
    $config=pncommerce_pmcreditapi_getConfig();
    //add value to array to make the function able to calculate the fee
    $config['Value']=$args['SubTotal'];
    return pnModAPIFunc('pncommerce','user','getPMCalcValue',$config);
}

/**
 * Asks for special data for this paymethod, for example minimum fee or default fee, ...
 * Account numbers, ...
 * ****
 * You have to redirect to 'paymethodconfig' when you're done
 * ****
 * @return String 
 * @returns the config page for this paymethod
 */
function pncommerce_pmcreditapi_config()
{
    if (!pnModAPILoad('pncommerce', 'admin')) {
        return showerrorpage("unable to load pnadminapi", __FILE__, __LINE__);
    }
    if (!pnModAPILoad('pncommerce', 'user')) {
        return showerrorpage("unable to load pnuserapi", __FILE__, __LINE__);
    }
    if (pnSecAuthAction(0, '::', '::', ACCESS_ADMIN)) {
        $Submit = pnVarCleanFromInput( 'Submit' );
        if( !$Submit ) {
            $smarty =& new pnRender('pncommerce');
            $smarty->caching = false;
            $config = pncommerce_pmcreditapi_getConfig();
            $smarty->assign( 'config', $config );
            if( $config['usemcrypt'] == 'on' ) {
                $smarty->assign( 'usemcrypt', 'checked' );
            }
            if( $config['card1'] == 'on' ) {
                $smarty->assign( 'card1checked', 'checked' );
            }
            if( $config['card2'] == 'on' ) {
                $smarty->assign( 'card2checked', 'checked' );
            }
            if( $config['card3'] == 'on' ) {
                $smarty->assign( 'card3checked', 'checked' );
            }
            return $smarty->fetch( 'pncommerce_pmcredit_configuration.html' );
        } else { // submit is set
    
            if( !pnSecConfirmAuthKey() ) { 
                return showerrorpage( _PNC_BADAUTHKEY, __FILE__, __LINE__ ); 
            }     
    
            $storage=array();
            $storage['mcryptkey'] = pnVarCleanFromInput( 'mcryptkey' );
            $storage['usemcrypt'] = pnVarCleanFromInput( 'usemcrypt' );
            $storage['card1'] = pnVarCleanFromInput( 'card1' );
            $storage['card2'] = pnVarCleanFromInput( 'card2' );
            $storage['card3'] = pnVarCleanFromInput( 'card3' );
            $storage['PMCalcFunc'] = pnVarCleanFromInput('PMCalcFunc');
            $storage=pnModAPIFunc('pncommerce','user','gatherPMCalcData',$storage);
            pncommerce_pmcreditapi_setConfig($storage);
            if( ($storage['card1']=='') && ($storage['card2']=='') && ($storage['card2']=='') ) {
                pnSessionSetVar( 'errormsg', _PNC_YOUMUSTENABLEATLEASTONECARD );
                pnRedirect( pnModAPIFunc('pncommerce','user','pncModURL',
                                        array('Module'=>'pncommerce', 'Section'=> 'pmcreditapi', 'Function'=>'config')));
                return true;
            } 
            pnRedirect( pnModAPIFunc('pncommerce','user','pncModURL',
                                    array('Module'=>'pncommerce', 'Section'=> 'admin', 'Function'=>'paymethodconfig')));
            return true; 
        }
    }
    return false;
}

/**
 * encrypt
 *
 */
function encrypt($ccnum)
{
    $config = pncommerce_pmcreditapi_getConfig();
    if($config['usemcrypt']=='on') {
        // Encryption...
        $td = mcrypt_module_open(MCRYPT_TripleDES, "", MCRYPT_MODE_ECB, "");
        srand((float)microtime() * 1000000);
        $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size ($td), MCRYPT_RAND);
        mcrypt_generic_init($td, $config['mcryptkey'], $iv);
        $ccnum = mcrypt_generic($td, $ccnum );
        // store CCNum|iv
        $ccnum = $ccnum."|".$iv;
    }   
    return $ccnum;
}

/**
 * decrypt
 *
 */
function decrypt($ccnum)
{
    $config = pncommerce_pmcreditapi_getConfig();
    if( !empty($ccnum) && ($config['usemcrypt'] == 'on')) {
        // Decryption ...
        list($ccnum, $iv) = explode("|", $ccnum);
        $td = mcrypt_module_open(MCRYPT_TripleDES, "", MCRYPT_MODE_ECB, "");
        mcrypt_generic_init($td, $config['mcryptkey'], $iv);
        $ccnum = trim(mdecrypt_generic($td, $ccnum));
        if(!pnSecAuthAction(0, 'pncommerce::', '::', ACCESS_ADMIN)) {
            // replace CCNum w/ XXX's etc...
            $part = substr($ccnum, strlen($ccnum)-4);
            $ccnum = "XXXX XXXX XXXX $part";
        }        
    }
    return $ccnum;
}

?>